package xyz.eden.boot.common.web.support.application.base;

import com.github.pagehelper.Page;
import org.springframework.beans.factory.annotation.Autowired;
import xyz.eden.boot.common.web.support.application.base.converter.BaseServiceConverter;
import xyz.eden.boot.common.web.support.application.base.dto.BaseInfoDTO;
import xyz.eden.boot.common.web.support.application.base.dto.BaseInfoQueryDTO;
import xyz.eden.boot.common.web.support.application.base.dto.BaseInfoUpdateDTO;
import xyz.eden.boot.common.web.support.infrastructure.resource.db.po.BasePO;
import xyz.eden.boot.core.exception.ParameterException;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * BaseService
 *
 * @author gavin
 * @version 1.0
 * @descriptor
 * @date 2023/4/28 9:36
 */
@SuppressWarnings("unchecked")
public abstract class BaseService<Resource extends IBaseResource<PO>, PO extends BasePO,
        QryDTO extends BaseInfoQueryDTO, UpdateDTO extends BaseInfoUpdateDTO, DTO extends BaseInfoDTO,
        Converter extends BaseServiceConverter<PO, DTO>> {

    @Autowired
    protected Resource resource;
    @Autowired
    private Converter converter;

    public Resource getResource() {
        return resource;
    }

    public Converter getConverter() {
        return converter;
    }

    public Boolean batchRemoveInfoById(List<Long> idList) {
        return resource.removeBatchByIds(idList);
    }

    public Boolean removeInfoById(Long id) throws Exception {
        return resource.removeById(id);
    }

    public Boolean updateInfoById(UpdateDTO dto) throws Exception {
        PO po = this.builderUpdateInfo(dto);
        AssertUtil.notNull(po, new ParameterException("参数不合法"));

        po.setUpdateTime(System.currentTimeMillis());
        return resource.updateById(po);
    }

    protected abstract PO builderUpdateInfo(UpdateDTO dto);

    public Boolean addInfo(UpdateDTO dto) throws Exception {

        PO po = this.builderAddInfo(dto);
        AssertUtil.notNull(po, new ParameterException("参数不合法"));

        po.setCreateTime(System.currentTimeMillis());
        po.setUpdateTime(System.currentTimeMillis());
        return resource.save(po);
    }

    protected abstract PO builderAddInfo(UpdateDTO dto);

    public DTO getInfoById(Long id) {
        PO po = resource.getById(id);
        return converter.builderDTO(po);
    }


    public PageDTO<DTO> getListByPage(int offset, int limit, QryDTO dto) {
        PO po = this.builderInfoQueryParam(dto);
        Page<PO> page = resource.getListByPage(offset, limit, po);
        List<DTO> dtoList = Optional.of(page.getResult()).orElse(Collections.emptyList())
                .stream().map(converter::builderDTO)
                .filter(Objects::nonNull).toList();
        return new PageDTO<>(0, 10, (int) page.getTotal(), dtoList);
    }


    public List<DTO> getInfoByParam(QryDTO dto) {
        PO po = this.builderInfoQueryParam(dto);
        List<PO> poList = resource.getListByParam(po);
        return Optional.of(poList).orElse(Collections.emptyList())
                .stream().map(converter::builderDTO)
                .filter(Objects::nonNull).toList();
    }

    protected abstract PO builderInfoQueryParam(QryDTO dto);

    public List<DTO> getList() {
        List<PO> poList = resource.list();
        return Optional.of(poList).orElse(Collections.emptyList())
                .stream().map(converter::builderDTO)
                .filter(Objects::nonNull).toList();
    }
}
